iT邦幫忙

2024 iThome 鐵人賽

DAY 28
0
JavaScript

PM說: RD大大,這個功能要怎麼寫啊?系列 第 28

PM 說: 前端怎麼知道網路斷線?

  • 分享至 

  • xImage
  •  

前言

試想一個情境
如果是在手機網路訊號不好的地方,使用者剛好在操作網頁
而網頁是SPA(Single Page Application),只會call API不會有網址切換的行為

有什麼方式能快速提醒使用者呢?
總不能都靠請求設定的timeout吧>>這樣還要等超時候才知道是網路問題
我們需要更直接的方式

看看 Youtube App 的範例:
yt

今天來實現類似的範例MVP


重點

  • online 事件
  • offline 事件
  • navigator.onLine

我們需要事件監聽online offline 來觸發我們定義的 function
並判斷navigator.onLine true/false 去改變UI就能完成目標

      function updateOnlineStatus() {
        clearTimeout(offlineTimer);
        clearTimeout(onlineTimer);
        // Online
        if (navigator.onLine) {
          statusBar.classList.remove("offline");
          statusBar.classList.add("online");
          statusBar.style.opacity = "1";
          onlineTimer = setTimeout(() => {
            statusBar.style.opacity = "0";
          }, 3000);
          return;
        }

        // Offline
        offlineTimer = setTimeout(() => {
          statusBar.classList.remove("online");
          statusBar.classList.add("offline");
          statusBar.style.opacity = "1";
        }, 2000);
      }

      window.addEventListener("online", updateOnlineStatus);
      window.addEventListener("offline", updateOnlineStatus);

值得注意的是:

  • online 出現的綠色bar不能一直出現會影響體驗
  • offline 則是超過一定時間才會出現(防止瞬間斷線又馬上連線的情況)

因此透過 setTimeout 來解決這2個優化的議題


成果

可以嘗試中斷網路測試看看
補充: 電腦版模擬斷線的開發小技巧

監聽網路斷線_demo

demo

程式碼

<!DOCTYPE html>
<html lang="zh-TW">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>web-navigator-online</title>
    <style>
      #status-bar {
        position: fixed;
        top: 0;
        left: 0;
        right: 0;
        height: 5px;
        transition: opacity 0.5s ease-in-out;
        opacity: 0;
      }
      .online {
        background-color: #4caf50;
      }
      .offline {
        background-color: #f44336;
      }
    </style>
  </head>
  <body>
    <div id="status-bar"></div>

    <h3>監聽網路 online & offline 會出現一條bar</h3>
    <pre>
        這個範例類似 Youtube App 
        <span style="color: #4caf50;">綠色</span>:有網路時出現(僅出現3秒)
        <span style="color: #f44336;">紅色</span>:超過2秒沒網路時出現(一直出現)
    </pre>

    <script>
      const statusBar = document.getElementById("status-bar");
      let onlineTimer;
      let offlineTimer;

      function updateOnlineStatus() {
        clearTimeout(offlineTimer);
        clearTimeout(onlineTimer);
        // Online
        if (navigator.onLine) {
          statusBar.classList.remove("offline");
          statusBar.classList.add("online");
          statusBar.style.opacity = "1";
          onlineTimer = setTimeout(() => {
            statusBar.style.opacity = "0";
          }, 3000);
          return;
        }

        // Offline
        offlineTimer = setTimeout(() => {
          statusBar.classList.remove("online");
          statusBar.classList.add("offline");
          statusBar.style.opacity = "1";
        }, 2000);
      }

      window.addEventListener("online", updateOnlineStatus);
      window.addEventListener("offline", updateOnlineStatus);

      // 初始狀態檢查
      updateOnlineStatus();
    </script>
  </body>
</html>


上一篇
PM 說: Line Notify 免費的限制是什麼?
下一篇
前端工程師說: 部署 Node.js 到 Vercel 怎麼設定變數?
系列文
PM說: RD大大,這個功能要怎麼寫啊?30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言